#include "insaertcolumndialog.h"
#include "ui_insaertcolumndialog.h"
#include "datamanagement/mainwindows/mainwindow.h"

insaertColumnDialog::insaertColumnDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::insaertColumnDialog)
{
    ui->setupUi(this);
    // 去掉问号，设置最小化、最大化、关闭
    setWindowFlags(Qt::Dialog | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
    setWindowTitle("新增字段数据");
    // 加载默认布局
    userDefinedlayout();
}

insaertColumnDialog::~insaertColumnDialog()
{
    delete ui;
    // 循环删除界面输入框/下拉框对象
    QList<QObject*> edits =  inputTextMap.values();
    for(QObject* edit: edits) {
        delete edit;
    }
    // 清理映射集
    inputTextMap.clear();
}

void insaertColumnDialog::on_submit_pushButton_clicked()
{
    // 开启一个加载提示框
    LoadingDialog* loading = LoadingDialog::createLoading(this);

    qDebug()<<"进入插入"+UserDefineConstant::COLUMN_TABLE_NAME+"数据操作";
    QList<QString> columnZnNames = inputTextMap.keys();
    QList<QString> addColumnNames;
    QComboBox* tableZnNameComboBox = (QComboBox*) inputTextMap.value(UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE);
    QString tableZnName = tableZnNameComboBox->currentText().trimmed();
    QList<QPair<QString,QString>> columnNameAndValues;
    if(ObjectUtil::isEmpty(tableZnName)) {
        loading->close(); // 关闭加载提示框
        QMessageBox::information(this,"提示", "请选择"+UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE);
        return;
    }
    QList<QueryConditions> userdefineTableConditions;
    userdefineTableConditions.append(QueryConditions(UserDefineConstant::USERDEFINE_TABLE_COLUMN_TABLE_ZN_NAME, tableZnName, false, "=", "and"));
    QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(userdefineTableConditions);
    UserDefineTableEntity userDefineTableEntity = userDefineTableEntitys.at(0);
    QString tableName = userDefineTableEntity.tableName;
    for(QString columnZnName: columnZnNames) {
        QString columnName = tableZnColumnNameAndColumnNames.value(columnZnName);
        QString text = "";
        if(columnZnName == UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE
                || columnZnName == UserDefineConstant::TABLE_COLUMN_IS_UNIQUE_ZN_TITLE
                || columnZnName == UserDefineConstant::TABLE_COLUMN_IS_REQUIRED_ZN_TITLE) {
            QComboBox* comboBox = (QComboBox*) inputTextMap.value(columnZnName);
            text= comboBox->currentText().trimmed();
            if(columnZnName == UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE) {
                text = tableName;
            }
        } else {
            QLineEdit* lineEdit = (QLineEdit*) inputTextMap.value(columnZnName);
            text = lineEdit->text().trimmed();
        }
        qDebug()<<"填写数据："<<columnZnName<<"="<<text;
        if(ObjectUtil::isEmpty(text)) {
            loading->close(); // 关闭加载提示框
            QMessageBox::information(this,"提示",columnZnName+"请填写完整");
            return;
        }
        if(columnZnName == UserDefineConstant::TABLE_COLUMN_IS_UNIQUE_ZN_TITLE || columnZnName == UserDefineConstant::TABLE_COLUMN_IS_REQUIRED_ZN_TITLE) {
            qDebug()<<"填写数据是否为true："<<columnZnName<<","<<(text == UserDefineConstant::BOOL_ZN_NAME_TRUE);
            if(!(text == UserDefineConstant::BOOL_ZN_NAME_TRUE) && !(text == UserDefineConstant::BOOL_ZN_NAME_FALSE)) {
                loading->close(); // 关闭加载提示框
                QMessageBox::information(this,"提示",columnZnName+"请填写【"+UserDefineConstant::BOOL_ZN_NAME_TRUE+","+UserDefineConstant::BOOL_ZN_NAME_FALSE+"】");
                return;
            }
        }
        if(columnZnName == UserDefineConstant::TABLE_COLUMN_NAME_ZN_TITLE || columnZnName == UserDefineConstant::TABLE_COLUMN_ZN_NAME_ZN_TITLE) {
            QRegExp rx("^[a-zA-Z_]+$");
            if(columnZnName == UserDefineConstant::TABLE_COLUMN_NAME_ZN_TITLE && rx.indexIn(text) == -1) {
                loading->close(); // 关闭加载提示框
                QMessageBox::information(this,"提示",columnZnName+"请填写英文字母和下划线的组合词");
                return;
            }
            QList<QueryConditions> conditions;
            conditions.append(QueryConditions(UserDefineConstant::TABLE_CONNECT_TABLE, tableName, false, "=", "and"));
            conditions.append(QueryConditions(columnName, text, false, "=", "and"));
            int count = DataBaseOpt::selectAllCount(UserDefineConstant::COLUMN_TABLE_NAME, conditions);
            if(count > 0) {
                loading->close(); // 关闭加载提示框
                QMessageBox::information(this,"提示",columnZnName+"已存在，请重新输入");
                return;
            }
            if(columnZnName == UserDefineConstant::TABLE_COLUMN_NAME_ZN_TITLE) {
                addColumnNames.append(text);
            }
        }
        columnNameAndValues.append(qMakePair(columnName, text));
    }
    if(DataBaseManage::getDb().driver()->hasFeature(QSqlDriver::Transactions)) { // 判断是否支持事务
        if(DataBaseManage::getDb().transaction()) { // 判断是否开启事务成功
            QList<bool> isSucess;
            isSucess.append(DataBaseOpt::insertTableData(UserDefineConstant::COLUMN_TABLE_NAME, columnNameAndValues));
            isSucess.append(DataBaseOpt::addColumnForTable(tableName, addColumnNames));
            // 通过上面的逻辑判断事务，开启成功之后，所有通过QSqlQuery执行exec的操作都会进行保存成事务，而不会立即执行，马上提交数据到数据库
            // 而是会和数据库建立联系，验证你语句的正确性，比如数据库有个字段限制5个字符长度，我新增时写的10个字符长度，这时候exec操作会返回false
            // 对于事务的处理，在执行QSqlQuery执行exec之后，需要判断你执行的所有语句中是否含有执行失败，如果有，就应该rollback进行回滚
            // 通过commit提交事务，就是将数据实际写入数据库，这时候可能会有失败，我这里测试得到当我所有的exec都返回false，commit依然返回了true，
            // 我怀疑是不是只要不是什么特殊情况，比如连接远程数据库网络中断，才会返回false，所以通过commit来判断成功不可取，所以需要上面的判断，
            // 就可以解决出错后却不能回滚的问题，不应该直接commit来判断成功与否,可以把判断commit作为最后的托底保障，最主要的还是前面的判断
            if(isSucess.contains(false)) {
                if(!DataBaseManage::getDb().rollback()) {  //回滚
                    qDebug()<< DataBaseManage::getDb().lastError();
                }
            } else {
                if(!DataBaseManage::getDb().commit()) {  //提交
                    qDebug()<< DataBaseManage::getDb().lastError();
                    if(!DataBaseManage::getDb().rollback()) {  //回滚
                        qDebug()<< DataBaseManage::getDb().lastError();
                    }
                }
            }
            loading->close(); // 关闭加载提示框
            if(!isSucess.contains(false)) {
                close();
                // 刷新列表
                columnSettingDialog* columnSetting = (columnSettingDialog*) parentWidget();
                columnSetting->refreshCloumnTableData();

                // 刷新主界面左侧列表信息，和刷新主界面指定右侧tableZnName表格界面所有界面信息
                ((MainWindow* )UserDefineConstant::MAIN_WINDOW)->refreshClassifyListWidgetAndTableWidgetByTableZnName(tableZnName);
                QMessageBox::information(this,"成功","插入成功");
            } else {
                QMessageBox::information(this,"失败","插入失败");
            }
        } else {
            loading->close(); // 关闭加载提示框
            QMessageBox::information(this, "失败","开启数据库事务失败，操作失败");
        }
    } else {
        loading->close(); // 关闭加载提示框
        QMessageBox::information(this, "失败","不支持数据库事务，操作失败");
    }
}

void insaertColumnDialog::userDefinedlayout()
{
    // 删除窗口所有布局
    QLayout *dlayout = layout();
    delete dlayout;

    // 添加自定义字段表的属性字段中文标题和属性字段的映射关系
    tableZnColumnNameAndColumnNames.insert(UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE, UserDefineConstant::TABLE_CONNECT_TABLE);
    tableZnColumnNameAndColumnNames.insert(UserDefineConstant::TABLE_COLUMN_NAME_ZN_TITLE, UserDefineConstant::TABLE_COLUMN_NAME);
    tableZnColumnNameAndColumnNames.insert(UserDefineConstant::TABLE_COLUMN_ZN_NAME_ZN_TITLE, UserDefineConstant::TABLE_COLUMN_ZN_NAME);
    tableZnColumnNameAndColumnNames.insert(UserDefineConstant::TABLE_COLUMN_IS_UNIQUE_ZN_TITLE, UserDefineConstant::TABLE_COLUMN_IS_UNIQUE);
    tableZnColumnNameAndColumnNames.insert(UserDefineConstant::TABLE_COLUMN_IS_REQUIRED_ZN_TITLE, UserDefineConstant::TABLE_COLUMN_IS_REQUIRED);

    // 构造界面展示的属性名中文标题
    QList<QString> columns;
    columns.append(UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE);
    columns.append(UserDefineConstant::TABLE_COLUMN_NAME_ZN_TITLE);
    columns.append(UserDefineConstant::TABLE_COLUMN_ZN_NAME_ZN_TITLE);
    columns.append(UserDefineConstant::TABLE_COLUMN_IS_UNIQUE_ZN_TITLE);
    columns.append(UserDefineConstant::TABLE_COLUMN_IS_REQUIRED_ZN_TITLE);

    // 查询出所有的表信息
    QList<UserDefineTableEntity> userDefineTableEntitys = DataBaseOpt::selectAllUserDefineTable(QList<QueryConditions>());
    QList<QString> tableNames;
    for(UserDefineTableEntity entity: userDefineTableEntitys) {
        tableNames.append(entity.tableZnName);
    }
    QGridLayout* gridLayout = new QGridLayout();
    int row = 0;
    // 循环展示的属性中文标题，为每个中文标题添加对应的组件映射
    for(QString columnZnName:columns) {
        gridLayout->addWidget(new QLabel(columnZnName),row,0,1,1); // 界面添加属性lable显示
        if(columnZnName == UserDefineConstant::TABLE_CONNECT_TABLE_ZN_TITLE) { // 如果当前展示属性为“关联的表名”
            QComboBox* comboBox = new QComboBox();
            comboBox->addItems(QStringList(tableNames)); // 往下拉框中添加所有的表信息选项
            gridLayout->addWidget(comboBox,row,1,1,1); // 界面添加属性对应的下拉框
            inputTextMap.insert(columnZnName, comboBox); // 记录属性中文名和组件的映射关系
        } else if(columnZnName == UserDefineConstant::TABLE_COLUMN_IS_UNIQUE_ZN_TITLE || columnZnName == UserDefineConstant::TABLE_COLUMN_IS_REQUIRED_ZN_TITLE) { // 如果当前展示属性为“字段是否唯一”或“字段是否必填”
            QComboBox* comboBox = new QComboBox();
            comboBox->addItems({UserDefineConstant::BOOL_ZN_NAME_TRUE,UserDefineConstant::BOOL_ZN_NAME_FALSE}); // 往下拉框中添加（是、否）两个选项
            gridLayout->addWidget(comboBox,row,1,1,1); // 界面添加属性对应的下拉框
            inputTextMap.insert(columnZnName, comboBox); // 记录属性中文名和组件的映射关系
        } else {
            QLineEdit* lineEdit = new QLineEdit();
            gridLayout->addWidget(lineEdit,row,1,1,1); // 界面添加属性对应的输入框
            inputTextMap.insert(columnZnName, lineEdit); // 记录属性中文名和组件的映射关系
        }
        row++;
    }

    QPushButton* submitBtn = new QPushButton("添加"); // 构造添加提交按钮
    connect(submitBtn,SIGNAL(clicked()),this,SLOT(on_submit_pushButton_clicked())); // 为添加提交按钮绑定点击事件槽函数
    QVBoxLayout* vBoxLayout = new QVBoxLayout();
    vBoxLayout->addLayout(gridLayout);
    vBoxLayout->addWidget(submitBtn);
    // 设置窗口布局
    setLayout(vBoxLayout);
}
